<?php
// TODO Check overall tent capacity
class DynamicTentForm extends sfForm
{
  
  /**
   * @var Doctrine_Collection
   */
  private $tents;
  
  const MIN_NUM_FORMS = 5;
  const OPTION_NUM_PARTICIPANTS_IN_HOUSE = 'num_participants_in_house';
  const OPTION_NUM_PARTICIPANTS_IN_TENT = 'num_participants_in_tent';

  public function __construct (Doctrine_Collection $coll, $options = array())
  {
    if ($coll->getTable()
      ->getTableName() !== TentTable::getInstance()->getTableName())
    {
      throw new InvalidArgumentException();
    }
    
    $this->tents = $coll;
    parent::__construct(array(), $options);
  }

  public function configure ()
  {
    $num_existent_tents = count($this->tents);
    
    if ($num_existent_tents > 0)
    {
      foreach ($this->tents as $participant)
      {
        $this->addForm($participant);
      }
    }
    
//    if ($num_existent_tents < self::MIN_NUM_FORMS)
//    {
      $num_blank_tents = self::MIN_NUM_FORMS - $num_existent_tents;
      if($num_blank_tents <= 0) {
        $num_blank_tents = 1;
      }
      for ($i = 0; $i < $num_blank_tents; $i ++)
      {
        $this->addForm();
      }
//    }
    
    $this->widgetSchema->setNameFormat('dynamic_tents[%s]');
    
    $post_validator = new EmbeddedTentValidatorSchema();
    $post_validator->setOption(EmbeddedTentValidatorSchema::OPTION_ALLOW_EMPTY, true);
    $this->mergePostValidator($post_validator);
    
    $post_validator = new OverallTentCapacityValidatorSchema();
    $post_validator->setOption(OverallTentCapacityValidatorSchema::OPTION_OVERALL_CAPACITY_HOUSE, $this->getOption(self::OPTION_NUM_PARTICIPANTS_IN_HOUSE));
    $post_validator->setOption(OverallTentCapacityValidatorSchema::OPTION_OVERALL_CAPACITY_TENT, $this->getOption(self::OPTION_NUM_PARTICIPANTS_IN_TENT));
    $this->mergePostValidator($post_validator);
  }

  public function addForm (Tent $tent = null, $num = null)
  {
    if (is_null($num))
    {
      $num = $this->getNumEmbeddedForms();
    }
    $form = new EmbeddedTentForm($tent);
    $form->getWidgetSchema()
      ->setNameFormat('dynamic_tents[' . $num . '][%s]');
    $this->embedForm($num, $form);
  }

  public function getNumEmbeddedForms ()
  {
    return count($this->embeddedForms);
  }

  /**
   * @return array
   */
  public function getTentForms ()
  {
    $num_embedded_forms = $this->getNumEmbeddedForms();
    $forms = array();
    for ($i = 0; $i < $num_embedded_forms; $i ++)
    {
      $forms[] = $this[$i];
    }
    return $forms;
  }

  /**
   * @param integer $i
   * @return boolean
   */
  public function hasEmbeddedForm ($i)
  {
    return isset($this[$i]);
  }

  public function bind (array $taintedValues = null, array $taintedFiles = null)
  {
    foreach ($taintedValues as $i => $value)
    {
      if (is_numeric($i) && ! $this->hasEmbeddedForm($i))
      {
        $this->addForm();
      }
    }
    
    return parent::bind($taintedValues, $taintedFiles);
  }

  public function getTents ()
  {
    $tents = new Doctrine_Collection('Tent');
    $values = $this->getValues();
    //array_pop($values); // Dirty fix? But it works :)
    foreach($this->getEmbeddedForms() as $i => $form) {
      if($form instanceof EmbeddedTentForm && isset($values[$i])) {
        $tent = new Tent();
        $tent->setArray($values[$i]);
        $tents->add($tent);
      }
    }
    return $tents;
  }
  
  public function addPreviouslyAddedForms(array $taintedValues = null) {
    foreach ( $taintedValues as $key => $address ) {
      if (is_numeric($key) && ! isset ( $this[$key] )) {
        $this->addForm(null, $key);
      }
    }
  }
}